package org.nettyServer.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class ServerConnection implements CommandLineRunner {



    @Resource
    private ServerChannelInitializer serverChannelInitializer;

    private final String host="127.0.0.1"; //连接主机ip
    private Integer port=10086; //连接主机端口
    public EventLoopGroup group;
    public Channel channel;
    public ChannelFuture f;

    /**
     * 创建TCP长连接并实例化channel
     */
    @Validated
    public void run(String... args) {
        if(group!=null){
            group.shutdownGracefully();  //这里调用这个看看会不会释放
        }
        group = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(group) //1 设置reactor 线程
                    .option(ChannelOption.SO_KEEPALIVE, true) //1 设置通道选项
                    .channel(NioServerSocketChannel.class) //2 设置nio类型的channel
                    .childHandler(serverChannelInitializer);  //3 装配流水线
            //创建连接
            f = serverBootstrap.bind(host, port);

            //检测并执行断线重连
            f.addListener((ChannelFutureListener) channelFuture -> {
                if (!channelFuture.isSuccess()) {
                    final EventLoop loop = channelFuture.channel().eventLoop();
                    loop.schedule(() -> {
                        log.error("{} ： 服务端启动失败，开始重连操作...", host);
                        run(args);
                        //此处处理重连次数
                    }, 1L, TimeUnit.SECONDS);
                } else {
                    channel = channelFuture.channel();
                    log.info("服务端启动成功...");
                }
            });
        } catch (Exception e) {
            log.error(e.getMessage());

        }
    }

}
